package com.scanner.util;


import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.text.format.Formatter;
import android.widget.Toast;

import com.scanner.bean.AppUpdateInfo;
import com.scanner.hardware.MyApplication;
import com.scanner.hardware.R;
import com.scanner.net.DefaultObserver;
import com.scanner.net.HttpResult;
import com.scanner.net.MainFactory;
import com.scanner.net.NetworkApi;
import com.scanner.net.RxProgressListener;
import com.scanner.ui.AppVersionDialog;
import com.scanner.ui.DownLoadProgressDialog;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class CheckAppUpdateUtil {
    private final Activity context;
    private static CheckAppUpdateUtil checkAppUpdate = null;

    private static boolean isShow;
    private DownLoadProgressDialog downLoadProgressDialog;
    private OnAppDownSuccessListener successListener;

    private CheckAppUpdateUtil(Activity context){
        this.context = context;

    }

    public synchronized static CheckAppUpdateUtil getInstance(Activity context, boolean show){
        checkAppUpdate = new CheckAppUpdateUtil(context);
        isShow = show;
        return checkAppUpdate;
    }


    public void checkLastVersionFromService(){
            try {
                String updateUrl = NetworkApi.APPNEWUPDATEURL + context.getResources().getString(R.string.app_update_code);
                LogUtil.e("请求版本更新地址="+updateUrl);
                Observable<HttpResult<AppUpdateInfo>> httpResultObservable = MainFactory.getEmmServiceInstance().upDate(updateUrl);
                httpResultObservable.observeOn(AndroidSchedulers.mainThread())
                        .subscribeOn(Schedulers.io())
                        .subscribe(new DefaultObserver<HttpResult<AppUpdateInfo>>(context) {
                            @Override
                            public void onSuccess(HttpResult<AppUpdateInfo> response) {
                                final AppUpdateInfo result = response.getResult();
                                if(result != null){
                                    int appVersionCode = BaseUtils.getVersionCode(context);
                                    LogUtil.i("发现新版本号="+result.getVersionCode()+";版本名："+result.getVersionName());
                                    if(result.getVersionCode() > appVersionCode){//有新的版本
                                        AppVersionDialog appVersionDialog = AppVersionDialog.getInstance(result.getUpdateType());
                                        appVersionDialog.setContent(result.getRemark());
                                        appVersionDialog.setSize(Formatter.formatFileSize(context,result.getApplicationSize()*1024));
                                        appVersionDialog.addOnSureListener(() -> {
                                            //开始下载
                                            downLoadAppNew(result.getDownloadUrl());
                                        });
                                        appVersionDialog.show(((AppCompatActivity)context).getSupportFragmentManager(),"f");
                                    }else {
                                        LogUtil.e("是否为真"+isShow);
                                        if(isShow){
                                            Toast.makeText(context, context.getString(R.string.new_version),Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                }else {
                                    if(isShow){
                                        Toast.makeText(context, context.getString(R.string.new_version),Toast.LENGTH_SHORT).show();
                                    }
                                }
                            }

                            @Override
                            public void onFail(int code, String msg) {
                            }
                        });
        }catch (Exception e){
            LogUtil.e("请求错误"+e.getMessage());
        }

    }


    private void downLoadAppNew(String url){

        MainFactory.getRetrofit().downloadSigFile(url, FileUtil.APK, "scannerPublic.apk", new RxProgressListener() {
            @Override
            public void onStartDownload() {
                downLoadProgressDialog = DownLoadProgressDialog.getInstance();
                downLoadProgressDialog.show(((AppCompatActivity)context).getSupportFragmentManager(),"p");
            }

            @Override
            public void onProgress(int progress, long total) {
                LogUtil.i("下载进度"+progress+";文件大小"+total);
                downLoadProgressDialog.setProgressProcent(progress,total);
            }

            @Override
            public void onFinishDownload(File file) {
                if(downLoadProgressDialog != null){
                    downLoadProgressDialog.dissDialog();
                }
                if(successListener != null){
                    successListener.success(file.getAbsolutePath());
                }
              /*  //去安装
                installProcess();*/
            }

            @Override
            public void onFail(String errorInfo) {
                if(downLoadProgressDialog != null){
                    downLoadProgressDialog.dissDialog();
                }
            }
        });

    }


    public interface OnAppDownSuccessListener{
        void success(String apkPath);
    }

    public void appDownSuccessListener(OnAppDownSuccessListener successListener){
        this.successListener = successListener;
    }


    //安装应用的流程
    public void installProcess(String apkFileString) {
        boolean haveInstallPermission;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //先获取是否有安装未知来源应用的权限
            haveInstallPermission = context.getPackageManager().canRequestPackageInstalls();
            if (!haveInstallPermission) {//没有权限
                startInstallPermissionSettingActivity();
                return;
            }
        }
        install(apkFileString);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity() {
        Uri packageURI = Uri.parse("package:" + context.getPackageName());
        //注意这个是8.0新API
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,packageURI);
        context.startActivity(intent);
    }


    /**
     * 安装APK * * @param apkFile APK文件的本地路径
     */
    public void install(String apkFileString) {
        LogUtil.i("文件地址="+apkFileString);
        File apkFile = new File(apkFileString);
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            Uri uri;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                // Android 7.0以上不允许Uri包含File实际路径，需要借助FileProvider生成Uri（或者调低targetSdkVersion小于Android 7.0欺骗系统）

                uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", apkFile);
                LogUtil.e("要安装的地址:"+uri.getPath());
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            } else {
                uri = Uri.fromFile(apkFile);
            }

            intent.setDataAndType(uri, "application/vnd.android.package-archive");
            context.startActivity(intent);

        } catch (Throwable e) {
            Toast.makeText(context, "安装失败：" + e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }
    private PackageManager packageManager;
    public void slicentInsatllApp(String appUrl){
        LogUtil.i("解析apk进行安装="+appUrl);
        /* 集成到系统中的调用方式 */
        packageManager = context.getPackageManager();
        PackageInfo downLoadPackageInfo = packageManager.getPackageArchiveInfo(
                appUrl, PackageManager.GET_ACTIVITIES);// 从下载的apk取得包名
        String localPkgVersion = "";
        try {
            localPkgVersion = packageManager.getPackageInfo(
                    context.getPackageName(),
                    PackageManager.GET_UNINSTALLED_PACKAGES).versionName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (context.getPackageName().equals(downLoadPackageInfo.packageName)) {// 如果下载的apk包名等于当前客户端包名，就比较版本号判断是否安装
            if (downLoadPackageInfo.versionName.compareTo(localPkgVersion) <= 0) {
                return;// 版本不新，不安装
            }
        }
        LogUtil.i("解析apk开始安装");
        installApk(appUrl,downLoadPackageInfo.packageName);
    }

    /**
     * 静默安装
     * @param apkPath
     * @param packName
     */
    private void installApk(final String apkPath, final String packName){
        MyApplication.actionThreadPool.execute(() -> {
                Class<?> pmClz = packageManager.getClass();
                try {
                    if (Build.VERSION.SDK_INT >= 21) {
                        Class<?> aClass = Class.forName("android.app.PackageInstallObserver");
                        Constructor<?> constructor = aClass.getDeclaredConstructor();
                        constructor.setAccessible(true);
                        Object installObserver = constructor.newInstance();
                        Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, aClass, int.class, String.class);
                        method.setAccessible(true);
                        method.invoke(packageManager, Uri.fromFile(new File(apkPath)),
                                installObserver, 2, packName);
                    } else {
                        Method method = pmClz.getDeclaredMethod("installPackage", Uri.class,
                                Class.forName("android.content.pm.IPackageInstallObserver"), int.class, String.class);
                        method.setAccessible(true);
                        method.invoke(packageManager, Uri.fromFile(new File(apkPath)), null, 2, packName);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    LogUtil.e(e.getMessage());
                }
        });
    }

}
